home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsII / RealPixels / colrops.c < prev    next >
Text File  |  1992-06-16  |  4KB  |  178 lines

  1. /* Copyright (c) 1990 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)colrops.c 1.3 11/9/90 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Integer operations on COLR scanlines
  9.  */
  10.  
  11. #include "color.h"
  12.  
  13. #define MAXGSHIFT    15        /* maximum shift for gamma table */
  14.  
  15. static BYTE    g_mant[256], g_nexp[256];
  16.  
  17. static BYTE    g_bval[MAXGSHIFT+1][256];
  18.  
  19.  
  20. setcolrgam(g)            /* set gamma conversion */
  21. double    g;
  22. {
  23.     extern double    pow();
  24.     double    mult;
  25.     register int    i, j;
  26.                     /* compute colr -> gamb mapping */
  27.     for (i = 0; i <= MAXGSHIFT; i++) {
  28.         mult = pow(0.5, (double)(i+8));
  29.         for (j = 0; j < 256; j++)
  30.             g_bval[i][j] = 256.0 * pow((j+.5)*mult, 1.0/g);
  31.     }
  32.                     /* compute gamb -> colr mapping */
  33.     i = 0;
  34.     mult = 256.0;
  35.     for (j = 255; j > 0; j--) {
  36.         while ((g_mant[j] = mult * pow(j/256.0, g)) < 128) {
  37.             i++;
  38.             mult *= 2.0;
  39.         }
  40.         g_nexp[j] = i;
  41.     }
  42.     g_mant[0] = 0;
  43.     g_nexp[0] = COLXS;
  44. }
  45.  
  46.  
  47. colrs_gambs(scan, len)        /* convert scanline of colrs to gamma bytes */
  48. register COLR    *scan;
  49. int    len;
  50. {
  51.     register int    i, expo;
  52.  
  53.     while (len-- > 0) {
  54.         expo = scan[0][EXP] - COLXS;
  55.         if (expo < -MAXGSHIFT) {
  56.             if (expo < -MAXGSHIFT-8) {
  57.                 scan[0][RED] =
  58.                 scan[0][GRN] =
  59.                 scan[0][BLU] = 0;
  60.             } else {
  61.                 i = (-MAXGSHIFT-1) - expo;
  62.                 scan[0][RED] = 
  63.                 g_bval[MAXGSHIFT][((scan[0][RED]>>i)+1)>>1];
  64.                 scan[0][GRN] =
  65.                 g_bval[MAXGSHIFT][((scan[0][GRN]>>i)+1)>>1];
  66.                 scan[0][BLU] =
  67.                 g_bval[MAXGSHIFT][((scan[0][BLU]>>i)+1)>>1];
  68.             }
  69.         } else if (expo > 0) {
  70.             if (expo > 8) {
  71.                 scan[0][RED] =
  72.                 scan[0][GRN] =
  73.                 scan[0][BLU] = 255;
  74.             } else {
  75.                 i = (scan[0][RED]<<1 | 1) << (expo-1);
  76.                 scan[0][RED] = i > 255 ? 255 : g_bval[0][i];
  77.                 i = (scan[0][GRN]<<1 | 1) << (expo-1);
  78.                 scan[0][GRN] = i > 255 ? 255 : g_bval[0][i];
  79.                 i = (scan[0][BLU]<<1 | 1) << (expo-1);
  80.                 scan[0][BLU] = i > 255 ? 255 : g_bval[0][i];
  81.             }
  82.         } else {
  83.             scan[0][RED] = g_bval[-expo][scan[0][RED]];
  84.             scan[0][GRN] = g_bval[-expo][scan[0][GRN]];
  85.             scan[0][BLU] = g_bval[-expo][scan[0][BLU]];
  86.         }
  87.         scan[0][EXP] = COLXS;
  88.         scan++;
  89.     }
  90. }
  91.  
  92.  
  93. gambs_colrs(scan, len)        /* convert gamma bytes to colr scanline */
  94. register COLR    *scan;
  95. int    len;
  96. {
  97.     register int    nexpo;
  98.  
  99.     while (len-- > 0) {
  100.         nexpo = g_nexp[scan[0][RED]];
  101.         if (g_nexp[scan[0][GRN]] < nexpo)
  102.             nexpo = g_nexp[scan[0][GRN]];
  103.         if (g_nexp[scan[0][BLU]] < nexpo)
  104.             nexpo = g_nexp[scan[0][BLU]];
  105.         if (nexpo < g_nexp[scan[0][RED]])
  106.             scan[0][RED] = g_mant[scan[0][RED]]
  107.                     >> (g_nexp[scan[0][RED]]-nexpo);
  108.         else
  109.             scan[0][RED] = g_mant[scan[0][RED]];
  110.         if (nexpo < g_nexp[scan[0][GRN]])
  111.             scan[0][GRN] = g_mant[scan[0][GRN]]
  112.                     >> (g_nexp[scan[0][GRN]]-nexpo);
  113.         else
  114.             scan[0][GRN] = g_mant[scan[0][GRN]];
  115.         if (nexpo < g_nexp[scan[0][BLU]])
  116.             scan[0][BLU] = g_mant[scan[0][BLU]]
  117.                     >> (g_nexp[scan[0][BLU]]-nexpo);
  118.         else
  119.             scan[0][BLU] = g_mant[scan[0][BLU]];
  120.         scan[0][EXP] = COLXS - nexpo;
  121.         scan++;
  122.     }
  123. }
  124.  
  125.  
  126. shiftcolrs(scan, len, adjust)    /* shift a scanline of colors by 2^adjust */
  127. register COLR    *scan;
  128. register int    len;
  129. register int    adjust;
  130. {
  131.     while (len-- > 0) {
  132.         scan[0][EXP] += adjust;
  133.         scan++;
  134.     }
  135. }
  136.  
  137.  
  138. normcolrs(scan, len, adjust)    /* normalize a scanline of colrs */
  139. register COLR  *scan;
  140. int  len;
  141. int  adjust;
  142. {
  143.     register int  c;
  144.     register int  shift;
  145.  
  146.     while (len-- > 0) {
  147.         shift = scan[0][EXP] + adjust - COLXS;
  148.         if (shift > 0) {
  149.             if (shift > 8) {
  150.                 scan[0][RED] =
  151.                 scan[0][GRN] =
  152.                 scan[0][BLU] = 255;
  153.             } else {
  154.                 shift--;
  155.                 c = (scan[0][RED]<<1 | 1) << shift;
  156.                 scan[0][RED] = c > 255 ? 255 : c;
  157.                 c = (scan[0][GRN]<<1 | 1) << shift;
  158.                 scan[0][GRN] = c > 255 ? 255 : c;
  159.                 c = (scan[0][BLU]<<1 | 1) << shift;
  160.                 scan[0][BLU] = c > 255 ? 255 : c;
  161.             }
  162.         } else if (shift < 0) {
  163.             if (shift < -8) {
  164.                 scan[0][RED] =
  165.                 scan[0][GRN] =
  166.                 scan[0][BLU] = 0;
  167.             } else {
  168.                 shift = -1-shift;
  169.                 scan[0][RED] = ((scan[0][RED]>>shift)+1)>>1;
  170.                 scan[0][GRN] = ((scan[0][GRN]>>shift)+1)>>1;
  171.                 scan[0][BLU] = ((scan[0][BLU]>>shift)+1)>>1;
  172.             }
  173.         }
  174.         scan[0][EXP] = COLXS - adjust;
  175.         scan++;
  176.     }
  177. }
  178.